package com.rbac.admin.service.system.impl;

import com.rbac.admin.entity.system.SysDictField;
import com.rbac.admin.mapper.system.SysDictionaryMapper;
import com.rbac.admin.service.system.SysDictionaryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;
import com.rbac.admin.dto.system.ColumnDefinitionDTO;

@Service
@RequiredArgsConstructor
public class SysDictionaryServiceImpl implements SysDictionaryService {

    private final SysDictionaryMapper dictionaryMapper;
    private final JdbcTemplate jdbcTemplate;

    @Override
    public List<Map<String, Object>> getTables(String tableName, String comment) {
        return dictionaryMapper.selectTables(tableName, comment);
    }

    @Override
    public List<Map<String, Object>> getColumns(String tableName, String columnName) {
        return dictionaryMapper.selectColumns(tableName, columnName);
    }

    @Override
    public void saveFields(List<SysDictField> fields) {
        if (fields == null || fields.isEmpty()) return;
        dictionaryMapper.batchInsertOrUpdateFields(fields);
    }

    @Override
    public void createTable(String tableName, List<ColumnDefinitionDTO> columns, String comment) {
        if (!StringUtils.hasText(tableName) || columns == null || columns.isEmpty()) return;
        StringBuilder sb = new StringBuilder();
        sb.append("CREATE TABLE IF NOT EXISTS `").append(tableName).append("` (");
        boolean first = true;
        String pk = null;
        for (ColumnDefinitionDTO c : columns) {
            if (!first) sb.append(",");
            first = false;
            sb.append("`").append(c.getColumnName()).append("` ");
            sb.append(buildColumnType(c));
            sb.append(c.getNullable() != null && !c.getNullable() ? " NOT NULL" : " NULL");
            if (StringUtils.hasText(c.getDefaultValue())) {
                sb.append(" DEFAULT '").append(c.getDefaultValue().replace("'","''")).append("'");
            }
            if (StringUtils.hasText(c.getComment())) {
                sb.append(" COMMENT '").append(c.getComment().replace("'","''")).append("'");
            }
            if (Boolean.TRUE.equals(c.getAutoIncrement())) {
                sb.append(" AUTO_INCREMENT");
            }
            if (Boolean.TRUE.equals(c.getUnique())) {
                sb.append(", UNIQUE KEY `uk_").append(c.getColumnName()).append("`(`").append(c.getColumnName()).append("`)");
            }
            if (Boolean.TRUE.equals(c.getPrimaryKey())) {
                pk = c.getColumnName();
            }
        }
        if (pk != null) {
            sb.append(", PRIMARY KEY (`").append(pk).append("`)");
        }
        sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
        if (StringUtils.hasText(comment)) {
            sb.append(" COMMENT='").append(comment.replace("'","''")).append("'");
        }
        jdbcTemplate.execute(sb.toString());
    }

    @Override
    public void addColumns(String tableName, List<ColumnDefinitionDTO> columns) {
        if (!StringUtils.hasText(tableName) || columns == null || columns.isEmpty()) return;
        for (ColumnDefinitionDTO c : columns) {
            StringBuilder sb = new StringBuilder();
            sb.append("ALTER TABLE `").append(tableName).append("` ADD COLUMN ");
            sb.append("`").append(c.getColumnName()).append("` ").append(buildColumnType(c));
            sb.append(c.getNullable() != null && !c.getNullable() ? " NOT NULL" : " NULL");
            if (StringUtils.hasText(c.getDefaultValue())) {
                sb.append(" DEFAULT '").append(c.getDefaultValue().replace("'","''")).append("'");
            }
            if (StringUtils.hasText(c.getComment())) {
                sb.append(" COMMENT '").append(c.getComment().replace("'","''")).append("'");
            }
            jdbcTemplate.execute(sb.toString());
            if (Boolean.TRUE.equals(c.getUnique())) {
                jdbcTemplate.execute("ALTER TABLE `" + tableName + "` ADD UNIQUE KEY `uk_" + c.getColumnName() + "`(`" + c.getColumnName() + "`)");
            }
        }
    }

    private String buildColumnType(ColumnDefinitionDTO c) {
        String type = c.getDataType();
        if (type == null) return "varchar(255)";
        type = type.toLowerCase();
        switch (type) {
            case "varchar":
                return "varchar(" + (c.getLength() != null ? c.getLength() : 255) + ")";
            case "decimal":
                int len = c.getLength() != null ? c.getLength() : 10;
                int sc = c.getScale() != null ? c.getScale() : 2;
                return "decimal(" + len + "," + sc + ")";
            case "int":
            case "bigint":
            case "tinyint":
            case "datetime":
            case "date":
            case "text":
                return type;
            default:
                return type;
        }
    }
}


